package solitaire.presentation;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Window;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragSource;
import java.awt.dnd.DragSourceDragEvent;
import java.awt.dnd.DragSourceDropEvent;
import java.awt.dnd.DragSourceEvent;
import java.awt.dnd.DragSourceListener;
import java.awt.dnd.DragSourceMotionListener;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JWindow;
import javax.swing.WindowConstants;

import solitaire.controle.*;

public class PSabot extends JPanel{
	
	private static final long serialVersionUID = 1L;
	
	private PTasDeCartes cachees;
	private PTasDeCartes visibles;
	private CSabot controller;
	
	private RetournerCarte retournerCarteListener;
	private RetournerTas retournerTasListener;
	
	private Window draggedCard = null;
	private PCarte selectedCard = null;
	private DragGestureEvent theInitialEvent ;
	
	private DragSource dragSource = null ;
	private MyDragSourceListener myDragSourceListener = null ;
	private MyDragSourceMotionListener myDragSourceMotionListener = null ;
	
	private JPanel backgroundCacheesPanel;
	
	public PSabot(PTasDeCartes tas1, PTasDeCartes tas2, CSabot controller)
	{
		this.cachees = tas1;
		this.visibles = tas2;
		this.controller = controller;
		
		this.retournerCarteListener = new RetournerCarte();
		this.retournerTasListener = new RetournerTas();
		
		setSize(PCarte.largeur + 15 + PCarte.largeur + 23 * 15, 101);
		setPreferredSize(getSize());
		
		backgroundCacheesPanel = new JPanel();
		backgroundCacheesPanel.setSize(PCarte.largeur, PCarte.hauteur);
		backgroundCacheesPanel.setPreferredSize(backgroundCacheesPanel.getSize());
		backgroundCacheesPanel.setLocation(0, 0);
		backgroundCacheesPanel.setBackground(new Color((float)0, (float)0, (float)0, (float)0));
		this.add(backgroundCacheesPanel, 0);
		
		backgroundCacheesPanel.setBorder(BorderFactory.createLineBorder(Color.black));
		
		this.setLayout(null);
		
		this.add(cachees, 0);
		cachees.setDX(0);
		cachees.setDY(0);
		this.add(visibles, 0);
		visibles.setDX(15);
		visibles.setDY(0);
		
		cachees.setLocation(0, 0);
		visibles.setLocation(PCarte.largeur + 15, 0);
		
		cachees.addMouseListener(retournerCarteListener);
		
		myDragSourceListener = new MyDragSourceListener () ;
		dragSource = new DragSource () ;
		dragSource.createDefaultDragGestureRecognizer (visibles, DnDConstants.ACTION_MOVE,
				new MyDragGestureListener ()) ;
		myDragSourceMotionListener = new MyDragSourceMotionListener () ;
		dragSource.addDragSourceMotionListener (myDragSourceMotionListener) ;
	}
	
	class RetournerCarte implements MouseListener {

		public void mouseClicked(MouseEvent ae) {
			try {
				controller.retournerCarte();
				controller.retournerCarte();
				controller.retournerCarte();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		public void mouseEntered(MouseEvent e) {}

		public void mouseExited(MouseEvent e) {}

		public void mousePressed(MouseEvent e) {}

		public void mouseReleased(MouseEvent e) {}
	}

	class RetournerTas implements MouseListener {

		public void mouseClicked(MouseEvent ae) {
			try {
				controller.retouner();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		public void mouseEntered(MouseEvent e) {}

		public void mouseExited(MouseEvent e) {}

		public void mousePressed(MouseEvent e) {}

		public void mouseReleased(MouseEvent e) {}
	}
	
	public void activerRetournerCarte() {
		cachees.addMouseListener(retournerCarteListener);
	}
	
	public void desactiverRetournerCarte() {
		cachees.removeMouseListener(retournerCarteListener);
	}

	public void activerRetournerTas() {
		backgroundCacheesPanel.addMouseListener(retournerTasListener);
	}

	public void desactiverRetournerTas() {
		backgroundCacheesPanel.removeMouseListener(retournerTasListener);
	}
	
	class MyDragSourceMotionListener implements DragSourceMotionListener {
		public void dragMouseMoved (DragSourceDragEvent event) {
			draggedCard.setLocation (1 + event.getX (), 1 + event.getY ()) ;
		}
	}
	
	protected class MyDragGestureListener implements DragGestureListener {
		public void dragGestureRecognized (DragGestureEvent event) {
			selectedCard = null ;
			try {
				selectedCard = (PCarte)visibles.getComponentAt (event.getDragOrigin ()) ;
			} catch (Exception e) {
				
			}
			if (selectedCard != null && visibles.getComponentZOrder(selectedCard) == 0){
				theInitialEvent = event ;
				
				CTasDeCartes ctdc = new CTasDeCartes("draggedTasDeCartes", new CUsine());
				ctdc.empiler(selectedCard.getControle());
				
				try {
					controller.depiler();
				} catch (Exception e) {
				}
				
				dragSource.startDrag(event, DragSource.DefaultMoveDrop, ctdc.getPresentation(), myDragSourceListener);
				
				draggedCard = new Window ((Window)(getRootPane ().getParent ())) ;
				draggedCard.add(ctdc.getPresentation());
				draggedCard.pack () ;
				draggedCard.setVisible (true) ;
				validate () ;
				repaint () ;
			} else {
				
			}
		}
	}
	
	protected class MyDragSourceListener implements DragSourceListener {

		public void dragDropEnd (DragSourceDropEvent event) {
			if (! event.getDropSuccess ()) {
				selectedCard.setLocation(20, 0);
				controller.empiler(selectedCard.getControle());
				visibles.validate () ;
				visibles.repaint () ;
			}
			draggedCard.setVisible (false) ;
		}

		public void dragEnter (DragSourceDragEvent event) {
		}

		public void dragExit (DragSourceEvent event) {
		}

		public void dragOver (DragSourceDragEvent event) {
		}

		public void dropActionChanged (DragSourceDragEvent event) {
		}

	}
	
	public static void main (String args []) {
		JFrame f = new JFrame ("Test PSabot") ;
		f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		f.getContentPane().setBackground(new Color(143, 143, 195));

		PCarte c1 = new PCarte ("QH", null);
		c1.setFaceVisible(true);

		PCarte c2 = new PCarte("1D", null);
		c2.setFaceVisible(true);
		
		PCarte c3 = new PCarte("1D", null);
		c3.setFaceVisible(false);
		
		PCarte c4 = new PCarte("1D", null);
		c3.setFaceVisible(false);
		
		PTasDeCartes cachees = new PTasDeCartes(null);
		PTasDeCartes visibles = new PTasDeCartes(null);
		
		PSabot sabot = new PSabot(cachees, visibles, null);
		

		//cachees.empiler(c3);
		//cachees.empiler(c4);
		visibles.empiler(c2);
		visibles.empiler(c1);
		visibles.depiler(c1);
		
		f.getContentPane().add(sabot);
		
		f.setVisible (true) ;
		f.pack();
		
	    } // main

}
